﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Net.Http.Headers;
using Sunny.UI;
using System.Threading;
using System.Drawing.Drawing2D;
using Sunny.UI.Win32;
using Emgu.CV.OCR;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.MonthCalendar;

namespace AutoTestSystem
{
    public class TestClass
    {
        public int TestCount { get; set; }

        public float TestAngle { get; set; }


        //public bool TestBool { get; set; }

        //public Button button { get; set; }
    }
    public class ToolClass
    {
        public static int hMin = 0;
        public static int hMax = 255;
        public static int sMin = 0;
        public static int sMax = 255;
        public static int vMin = 0;
        public static int vMax = 255;

        //强制释放进程
        [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize")]
        public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);


        [DllImport("AspriseOCR.dll", EntryPoint = "OCR", CallingConvention = CallingConvention.Cdecl)]

        public static extern IntPtr OCR(string file, int type);

        [DllImport("AspriseOCR.dll", EntryPoint = "OCRpart", CallingConvention = CallingConvention.Cdecl)]

        static extern IntPtr OCRpart(string file, int type, int startX, int startY, int width, int height);

        [DllImport("AspriseOCR.dll", EntryPoint = "OCRBarCodes", CallingConvention = CallingConvention.Cdecl)]

        static extern IntPtr OCRBarCodes(string file, int type);

        [DllImport("AspriseOCR.dll", EntryPoint = "OCRpartBarCodes", CallingConvention = CallingConvention.Cdecl)]

        static extern IntPtr OCRpartBarCodes(string file, int type, int startX, int startY, int width, int height);




        [DllImport("user32.dll", EntryPoint = "SetCursorPos")]
        private static extern bool SetCursorPos(int x, int y);

        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]
        public static extern bool GetCursorPos(out System.Drawing.Point lpPoint);


        [DllImport("user32.dll")]
        public static extern bool EnumWindows(EnumWindowProc enumProc, IntPtr lParam);

        // 导入 GetWindowTextLength 函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowTextLength(IntPtr hWnd);

        // 导入 GetClassName 函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, char[] className, int maxCount);


        // 导入 GetClassName 函数
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int ShowWindow(IntPtr hWnd, int nCmd);

        // 导入 IsWindowVisible 函数
        [DllImport("user32.dll")]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        public delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);

        public static void MoveMouseTo(int x, int y)
        {
            SetCursorPos(x, y);
        }


        public static void GetMouse(int x, int y)
        {
            SetCursorPos(x, y);
        }

        public static string OcrCheck111(string file)
        {
            string result;

            using (Mat mat = CvInvoke.Imread(file, ImreadModes.Grayscale))
            {
                //Image<Bgr, Bitmap> image = new Image<Bgr, byte>(b);
                if (mat.IsEmpty)
                {
                    Console.WriteLine("Error: Unable to load image.");
                    //return;
                }

                Bitmap bitmap;
                if (mat.NumberOfChannels == 1) // 灰度图像
                {
                    Image<Gray, byte> grayImg = mat.ToImage<Gray, byte>();
                    // 由于 System.Drawing.Bitmap 不直接支持灰度像素格式，
                    // 我们将其转换为伪彩色图像（每个通道都设置为灰度值）。
                    // 注意：这可能会导致颜色信息的丢失，因为灰度图像没有颜色。
                    // 但对于 OCR 来说，这通常不是问题。
                    Image<Bgr, byte> colorImg = grayImg.Convert<Bgr, byte>();
                    //bitmap = colorImg.ToBitmap();

                    var copyImg=  colorImg.CopyBlank();

                    CvInvoke.Threshold(colorImg, copyImg, 255, 255, ThresholdType.Trunc);

                    bitmap = copyImg.ToBitmap();
                }
                else // 彩色图像（虽然这里我们指定了灰度加载，但为了一般性而保留此分支）
                {
                    Image<Bgr, byte> colorImg = mat.ToImage<Bgr, byte>();
                    //bitmap = colorImg.ToBitmap();

                    var copyImg = colorImg.CopyBlank();

                    CvInvoke.Threshold(colorImg, copyImg, 100, 255, ThresholdType.Binary);

                    bitmap = copyImg.ToBitmap();
                }

                //pb.BackgroundImage= bitmap;

                // 初始化 Tesseract OCR 引擎

                using (Tesseract engine = new Tesseract("tessdata", "eng", OcrEngineMode.Default))
                {
                    Mat imageGrayscale = BitmapExtension.ToMat(bitmap);
                    engine.SetImage(imageGrayscale);
                    result = engine.GetUTF8Text().Trim();
                }
            }

            return result;
        }

        public static string OcrCheckTest(string file,PictureBox pb)
        {
            string result;

            using (Mat mat = CvInvoke.Imread(file,ImreadModes.Color))//, ImreadModes.Grayscale
            {
                if (mat.IsEmpty)
                {
                    Console.WriteLine("Error: Unable to load image.");
                    //return;
                }
                Mat matTemp = new Mat();
                CvInvoke.CvtColor(mat, matTemp, ColorConversion.Bgr2Gray);                         
                Image<Gray, byte> grayImg = matTemp.ToImage<Gray, byte>();
                Bitmap bitmap = grayImg.Convert<Gray, byte>().ThresholdAdaptive(new Gray(255),
                AdaptiveThresholdType.GaussianC,
                ThresholdType.Binary,
                49,
                new Gray(50)).ToBitmap();
             
                pb.BackgroundImage= bitmap;

                using (Tesseract engine = new Tesseract("tessdata", "eng", OcrEngineMode.Default))
                {
                    Mat imageGrayscale = BitmapExtension.ToMat(bitmap);
                    engine.SetImage(imageGrayscale);
                    result = engine.GetUTF8Text().Trim();
                }

            }

            return result;
        }


        public static string OcrCheckMethod(string file)
        {
            string result;

            using (Mat mat = CvInvoke.Imread(file, ImreadModes.Color))//, ImreadModes.Grayscale
            {
                if (mat.IsEmpty)
                {
                    Console.WriteLine("Error: Unable to load image.");
                    //return;
                }
                Mat matTemp = new Mat();
                CvInvoke.CvtColor(mat, matTemp, ColorConversion.Bgr2Gray);
                Image<Gray, byte> grayImg = matTemp.ToImage<Gray, byte>();
                Bitmap bitmap = grayImg.Convert<Gray, byte>().ThresholdAdaptive(new Gray(255),
                AdaptiveThresholdType.GaussianC,
                ThresholdType.Binary,
                49,
                new Gray(50)).ToBitmap();

                using (Tesseract engine = new Tesseract("tessdata", "eng", OcrEngineMode.Default))
                {
                    Mat imageGrayscale = BitmapExtension.ToMat(bitmap);
                    engine.SetImage(imageGrayscale);
                    result = engine.GetUTF8Text().Trim();
                }

            }

            return result;
        }

        /// <summary>
        /// 图片二值化
        /// </summary>
        /// <param name="img"></param>
        /// <param name="blockSize"></param>
        /// <param name="val"></param>
        /// <returns></returns>
        public static Image<Gray, byte> BinImg(Image<Bgr, byte> img, int blockSize, int val)
        {
            return img.Convert<Gray, byte>().SmoothGaussian(5).ThresholdAdaptive(new Gray(255),
                AdaptiveThresholdType.GaussianC,
                ThresholdType.Binary,
                blockSize,
                new Gray(val));
        }
        public static string OcrCheck(string testpicture, int x, int y, int width, int height)
        {



            return Marshal.PtrToStringAnsi(OCRpart(testpicture, -1, x, y, width, height));

        }


        public static Bitmap CropImage(Bitmap originalBitmap, int x, int y, int width, int height)
        {
            Rectangle cropRect = new Rectangle(x, y, width, height);
            Bitmap croppedBitmap = originalBitmap.Clone(cropRect, originalBitmap.PixelFormat);
            return croppedBitmap;
        }

        /// <summary>
        /// 内存释放
        /// </summary>
        public static void DisposeMemory()
        {
            try
            {
                GC.Collect();

                GC.WaitForPendingFinalizers();

                if (Environment.OSVersion.Platform == PlatformID.Win32NT)
                {

                    SetProcessWorkingSetSize(System.Diagnostics.Process.GetCurrentProcess().Handle, -1, -1);

                }
            }
            catch { }

        }
        public static Stream BitmapToStream(Bitmap bitmap)
        {
            MemoryStream memoryStream = new MemoryStream();
            bitmap.Save(memoryStream, bitmap.RawFormat);
            byte[] bytes=new byte[memoryStream.Length];
            bytes=memoryStream.ToArray();
            Stream stream = new MemoryStream(bytes);
            return stream;
        }
     



      
        public static String openFile()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "图像文件|*.jpg;*.png;*.bmp;*.jpeg|全部文件|*.*";
            dialog.Multiselect = false;
            dialog.RestoreDirectory = true;
            dialog.FilterIndex = 1;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                String fileName = dialog.FileName;
                return fileName;
            }
            return null;
        }

        /**
         * 保存文件对话框
         */
        public static String saveFile()
        {
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = "*.jpg|*.png|*.bmp|*.*";
            dialog.RestoreDirectory = true;
            dialog.FilterIndex = 1;
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                String fileName = dialog.FileName;
                return fileName;
            }
            return null;
        }

        public static void LogShow(string str)
        {
            
        }
        public static string AreaPath = System.Windows.Forms.Application.StartupPath + @"\AreaImage";

        #region xml处理
        public static void IniLocData()
        {
            Form1.stepList.Clear();
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(Form1.locPath);

                XmlNodeList xmlNode = xmlDocument.SelectSingleNode("LocData").ChildNodes;

                foreach (XmlNode item in xmlNode)
                {
                    if (item.Name.ToLower() == "machine")
                    {
                        StepClass barcodeClass = new StepClass();

                        barcodeClass.StepName = item.Attributes["name"].Value;

                        foreach (XmlNode node in item.ChildNodes)
                        {
                            if (node.Name.ToLower() == "stepdetail")
                            { barcodeClass.StepDetail = node.InnerText; }
                            if (node.Name.ToLower() == "comparestr")
                            { barcodeClass.CompareStr = node.InnerText; }
                            if (node.Name.ToLower() == "isenable")
                            {
                                if (node.InnerText == "0")
                                {
                                    barcodeClass.IsEnable = "✘";
                                }
                                else
                                {
                                    barcodeClass.IsEnable = "✔";
                                    Form1.SelectedKind = "机种：" + barcodeClass.StepName + "      步骤：" + barcodeClass.StepDetail + "      文字：" + barcodeClass.CompareStr;
                                }
                            }
                            if (node.Name.ToLower() == "area") 
                            {
                                barcodeClass.Area=node.InnerText;
                            }
                        }



                        Form1.stepList.Add(barcodeClass);
                    }

                }
            }
            catch { MessageBox.Show("数据读取异常"); }

        }
        public static void RemoveAllLocData()
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(Form1.locPath);
                XmlNode xmlNode = xmlDocument.SelectSingleNode("LocData");
                xmlNode.RemoveAll();
                xmlDocument.Save(Form1.locPath);
                Form1.stepList.Clear();
                MessageBox.Show("数据清除完成");
            }
            catch { MessageBox.Show("数据读取异常"); }

        }
        public static void RemoveSingleLocData(StepClass bc)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(Form1.locPath);
                XmlNodeList xmlNode = xmlDocument.SelectSingleNode("LocData").ChildNodes;
                XmlNode xmlNodeAll = xmlDocument.SelectSingleNode("LocData");
                
                foreach (XmlNode item in xmlNode)
                {
                    if (item.Name.ToLower() == "machine")
                    {
                        XmlElement xe = (XmlElement)item;
                        if (xe.GetAttribute("name") == bc.StepName)
                        {
                            xmlNodeAll.RemoveChild(item);
                           
                            break;
                        }
                    }
                }
                  
                xmlDocument.Save(Form1.locPath);               
                MessageBox.Show("数据清除完成");
            }
            catch { MessageBox.Show("数据读取异常"); }

        }
        public static void AddLocData(StepClass bc)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(Form1.locPath);
                XmlNode xmlNode = xmlDocument.SelectSingleNode("LocData");
                XmlElement xmlElement = xmlDocument.CreateElement("Machine");
                xmlElement.SetAttribute("name", bc.StepName);
                XmlElement xmlElementSfc = xmlDocument.CreateElement("StepDetail");
                xmlElementSfc.InnerText = bc.StepDetail;
                XmlElement xmlElementUser = xmlDocument.CreateElement("CompareStr");
                xmlElementUser.InnerText = bc.CompareStr;
                XmlElement xmlElementTime = xmlDocument.CreateElement("IsEnable");
                if (bc.IsEnable == "✘")
                {
                    xmlElementTime.InnerText = "0";
                }
                else
                { xmlElementTime.InnerText = "1"; }

                XmlElement xmlElementArea = xmlDocument.CreateElement("Area");
                xmlElementArea.InnerText = bc.Area;

                xmlElement.AppendChild(xmlElementSfc);
                xmlElement.AppendChild(xmlElementUser);
                xmlElement.AppendChild(xmlElementTime);
                xmlElement.AppendChild(xmlElementArea);
                xmlNode.AppendChild(xmlElement);

                xmlDocument.Save(Form1.locPath);
            }
            catch { MessageBox.Show("数据读取异常"); }



            
        }
        public static void UpdateLocData(StepClass bc)
        {
            try
            {
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(Form1.locPath);

                XmlNodeList xmlNode = xmlDocument.SelectSingleNode("LocData").ChildNodes;

                foreach (XmlNode item in xmlNode)
                {
                    if (item.Name.ToLower() == "machine")
                    {
                        XmlElement xe = (XmlElement)item;
                        if (xe.GetAttribute("name") == bc.StepName)
                        {
                            foreach (XmlNode node in item.ChildNodes)
                            {
                                if (node.Name.ToLower() == "stepdetail")
                                {  node.InnerText= bc.StepDetail; }
                                if (node.Name.ToLower() == "comparestr")
                                { node.InnerText = bc.CompareStr; }
                                if (node.Name.ToLower() == "isenable")
                                {
                                    if (bc.IsEnable == "✘")
                                    {
                                        node.InnerText = "0";
                                    }
                                    else
                                    {
                                        node.InnerText = "1";
                                    }
                                }
                                if (node.Name.ToLower() == "area")
                                { node.InnerText = bc.Area; }
                            }

                            break;
                        }
                    }
                }




                xmlDocument.Save(Form1.locPath);
            }
            catch { MessageBox.Show("数据读取异常"); }

        }
        #endregion


        #region 毫秒延时
        public static void Delay(int mm)
        {
            DateTime current = DateTime.Now;
            while (current.AddMilliseconds(mm) > DateTime.Now)
            {
                try
                {
                    Thread.Sleep(1);//防止CPU
                    System.Windows.Forms.Application.DoEvents();
                }
                catch { continue; }

            }
        }
        #endregion

        public static void ConfigFiles()
        {
            if (!File.Exists(@"Config\Setting Config.ini"))
            {
                FileStream Config = File.Create(@"Config\Setting Config.ini");
                Config.Close();
                File.WriteAllLines(@"Config\Setting Config.ini", new string[] { "Enter" });
            }
        }

        public static Bitmap GetFile(string MachineName) 
        {
            Bitmap bitmap=null; 
            string[] files = Directory.GetFiles(AreaPath);

            // 遍历文件名并输出
            foreach (string file in files)
            {
                string extension = Path.GetExtension(file).ToLower();
                if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".gif" || extension == ".bmp")
                {
                    string fileName = Path.GetFileNameWithoutExtension(file);
                    if (MachineName==fileName) 
                    {
                        bitmap = new Bitmap(file);
                        return bitmap;
                    }
                    // 这里可以对图片文件进行进一步处理
                }



            }
            return bitmap;
        }


        //public static string GetFileName(string MachineName)
        //{
        //    Bitmap bitmap = null;
        //    string[] files = Directory.GetFiles(AreaPath);

        //    // 遍历文件名并输出
        //    foreach (string file in files)
        //    {
        //        string extension = Path.GetExtension(file).ToLower();
        //        if (extension == ".jpg" || extension == ".jpeg" || extension == ".png" || extension == ".gif" || extension == ".bmp")
        //        {
        //            string fileName = Path.GetFileNameWithoutExtension(file);
        //            if (MachineName == fileName)
        //            {
        //                bitmap = new Bitmap(file);
        //                return bitmap;
        //            }
        //            // 这里可以对图片文件进行进一步处理
        //        }



        //    }
        //    return bitmap;
        //}

        // 获取文件夹中的所有文件名

    }


    internal class ScreenClass
    {
        private enum processDpiAwareness
        {
            ProcessDPIUnaware = 0,
            ProcessSystemDPIAware = 1,
            ProcessPerMonitorDPIAware = 2
        };

        [DllImport("shcore.dll")]
        private static extern int SetProcessDpiAwareness(processDpiAwareness value);

        public static Bitmap GetFullScreenShot()
        {
            SetProcessDpiAwareness(processDpiAwareness.ProcessPerMonitorDPIAware);

            Screen sc = Screen.PrimaryScreen;                         //获取主屏
            Bitmap i = new Bitmap(sc.Bounds.Width, sc.Bounds.Height);
            //Bitmap i = new Bitmap(800, 600);
            Graphics g = Graphics.FromImage(i);
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.High;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            g.CopyFromScreen(new Point(0, 0), new Point(0, 0), sc.Bounds.Size);
            g.Dispose();

            return i;
        }
    }
}
